package com.franklin.ideaplugin.easytesting.vfs;


import com.intellij.lang.Language;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VFileProperty;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.ThreeState;
import com.intellij.util.keyFMap.KeyFMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.function.Supplier;

/**
 * @author Ye Junhui
 * @since 2023/8/9
 */
public class ExecuteMethodScriptVirtualFile extends LightVirtualFile {

    private final LightVirtualFile delegate;
    private final String fileUrl;
    

    public ExecuteMethodScriptVirtualFile(@NotNull LightVirtualFile delegate, String fileUrl) {
        this.delegate = delegate;
        this.fileUrl = fileUrl;
        this.delegate.copyUserDataTo(this);
    }

    public LightVirtualFile getDelegate() {
        return delegate;
    }

    @Override
    public Language getLanguage() {
        return this.delegate.getLanguage();
    }

    @Override
    public void setLanguage(@NotNull Language language) {
        this.delegate.setLanguage(language);
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return this.delegate.getInputStream();
    }

    @Override
    public @NotNull OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
        return this.delegate.getOutputStream(requestor, newModificationStamp, newTimeStamp);
    }

    @Override
    public byte @NotNull [] contentsToByteArray() throws IOException {
        return this.delegate.contentsToByteArray();
    }

    @Override
    public void setContent(Object requestor, @NotNull CharSequence content, boolean fireEvent) {
        this.delegate.setContent(requestor, content, fireEvent);
    }

    @Override
    public @NotNull CharSequence getContent() {
        return this.delegate.getContent();
    }

    @Override
    public @NotNull ThreeState isTooLargeForIntelligence() {
        return this.delegate.isTooLargeForIntelligence();
    }

    @Override
    public String toString() {
        return this.delegate.toString();
    }

    @Override
    public void setFileType(FileType fileType) {
        this.delegate.setFileType(fileType);
    }

    @Override
    public VirtualFile getOriginalFile() {
        return this.delegate.getOriginalFile();
    }

    @Override
    public void setOriginalFile(VirtualFile originalFile) {
        this.delegate.setOriginalFile(originalFile);
    }

    @Override
    public @NotNull VirtualFileSystem getFileSystem() {
        return this.delegate.getFileSystem();
    }

    @Override
    public @Nullable FileType getAssignedFileType() {
        return this.delegate.getAssignedFileType();
    }

    @Override
    public @NotNull String getPath() {
        return this.delegate.getPath();
    }

    @Override
    public @NlsSafe @NotNull String getName() {
        return this.delegate.getName();
    }

    @Override
    public boolean isWritable() {
        return this.delegate.isWritable();
    }

    @Override
    public boolean isDirectory() {
        return this.delegate.isDirectory();
    }

    @Override
    public boolean isValid() {
        return this.delegate.isValid();
    }

    @Override
    public void setValid(boolean valid) {
        this.delegate.setValid(valid);
    }

    @Override
    public VirtualFile getParent() {
        return this.delegate.getParent();
    }

    @Override
    public VirtualFile[] getChildren() {
        return this.delegate.getChildren();
    }

    @Override
    public long getModificationStamp() {
        return this.delegate.getModificationStamp();
    }


    @Override
    public long getTimeStamp() {
        return this.delegate.getTimeStamp();
    }

    @Override
    public long getLength() {
        return this.delegate.getLength();
    }

    @Override
    public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
        this.delegate.refresh(asynchronous, recursive, postRunnable);
    }

    @Override
    public void setWritable(boolean writable) {
        this.delegate.setWritable(writable);
    }

    @Override
    public void rename(Object requestor, @NotNull String newName) throws IOException {
        this.delegate.rename(requestor, newName);
    }

    @Override
    public @NotNull VirtualFile createChildDirectory(Object requestor, @NotNull String name) throws IOException {
        return this.delegate.createChildDirectory(requestor, name);
    }

    @Override
    public @NotNull VirtualFile createChildData(Object requestor, @NotNull String name) throws IOException {
        return this.delegate.createChildData(requestor, name);
    }

    @Override
    public void delete(Object requestor) throws IOException {
        this.delegate.delete(requestor);
    }

    @Override
    public void move(Object requestor, @NotNull VirtualFile newParent) throws IOException {
        this.delegate.move(requestor, newParent);
    }

    @Override
    public void setBinaryContent(byte @NotNull [] content, long newModificationStamp, long newTimeStamp) throws IOException {
        this.delegate.setBinaryContent(content, newModificationStamp, newTimeStamp);
    }

    @Override
    public void setBinaryContent(byte @NotNull [] content, long newModificationStamp, long newTimeStamp, Object requestor) throws IOException {
        this.delegate.setBinaryContent(content, newModificationStamp, newTimeStamp, requestor);
    }

    @Override
    public @NotNull @NlsSafe CharSequence getNameSequence() {
        return this.delegate.getNameSequence();
    }

    @Override
    public @NotNull Path toNioPath() {
        return this.delegate.toNioPath();
    }

    @Override
    public @NotNull String getUrl() {
        return this.delegate.getUrl();
    }

    @Override
    public @Nullable @NlsSafe String getExtension() {
        return this.delegate.getExtension();
    }

    @Override
    public @NlsSafe @NotNull String getNameWithoutExtension() {
        return this.delegate.getNameWithoutExtension();
    }

    @Override
    public boolean is(@NotNull VFileProperty property) {
        return this.delegate.is(property);
    }

    @Override
    public @Nullable String getCanonicalPath() {
        return this.delegate.getCanonicalPath();
    }

    @Override
    public @Nullable VirtualFile getCanonicalFile() {
        return this.delegate.getCanonicalFile();
    }

    @Override
    public @Nullable VirtualFile findChild(@NotNull @NonNls String name) {
        return this.delegate.findChild(name);
    }

    @Override
    public @NotNull VirtualFile findOrCreateChildData(Object requestor, @NotNull @NonNls String name) throws IOException {
        return this.delegate.findOrCreateChildData(requestor, name);
    }

    @Override
    public @NotNull FileType getFileType() {
        return this.delegate.getFileType();
    }

    @Override
    public @Nullable VirtualFile findFileByRelativePath(@NotNull @NonNls String relPath) {
        return this.delegate.findFileByRelativePath(relPath);
    }

    @Override
    public @NotNull VirtualFile copy(Object requestor, @NotNull VirtualFile newParent, @NotNull @NonNls String copyName) throws IOException {
        return this.delegate.copy(requestor, newParent, copyName);
    }

    @Override
    public @NotNull Charset getCharset() {
        return this.delegate.getCharset();
    }

    @Override
    public byte @NotNull [] contentsToByteArray(boolean cacheContent) throws IOException {
        return this.delegate.contentsToByteArray(cacheContent);
    }

    @Override
    public void refresh(boolean asynchronous, boolean recursive) {
        this.delegate.refresh(asynchronous, recursive);
    }

    @Override
    public @NlsSafe String getPresentableName() {
        return this.delegate.getPresentableName();
    }

    @Override
    public long getModificationCount() {
        return this.delegate.getModificationCount();
    }

    @Override
    public byte @Nullable [] getBOM() {
        return this.delegate.getBOM();
    }

    @Override
    public void setBOM(byte @Nullable [] BOM) {
        this.delegate.setBOM(BOM);
    }

    @Override
    public boolean exists() {
        return this.delegate.exists();
    }

    @Override
    public boolean isInLocalFileSystem() {
        return this.delegate.isInLocalFileSystem();
    }

    @Override
    public @Nullable @NlsSafe String getDetectedLineSeparator() {
        return this.delegate.getDetectedLineSeparator();
    }

    @Override
    public void setDetectedLineSeparator(@Nullable String separator) {
        this.delegate.setDetectedLineSeparator(separator);
    }

    @Override
    public <T> T computeWithPreloadedContentHint(byte @NotNull [] preloadedContentHint, @NotNull Supplier<? extends T> computable) {
        return this.delegate.computeWithPreloadedContentHint(preloadedContentHint, computable);
    }

    @Override
    public boolean isRecursiveOrCircularSymlink() {
        return this.delegate.isRecursiveOrCircularSymlink();
    }

    @Override
    public boolean isCaseSensitive() {
        return this.delegate.isCaseSensitive();
    }

    @Override
    public String getUserDataString() {
        return this.delegate.getUserDataString();
    }

    @Override
    public void copyUserDataTo(@NotNull UserDataHolderBase other) {
        this.delegate.copyUserDataTo(other);
    }

    @Override
    public <T> T getCopyableUserData(@NotNull Key<T> key) {
        return this.delegate.getCopyableUserData(key);
    }

    @Override
    public <T> void putCopyableUserData(@NotNull Key<T> key, T value) {
        this.delegate.putCopyableUserData(key, value);
    }

    @Override
    public <T> boolean replace(@NotNull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
        return this.delegate.replace(key, oldValue, newValue);
    }

    @Override
    public <T> @NotNull T putUserDataIfAbsent(@NotNull Key<T> key, @NotNull T value) {
        return this.delegate.putUserDataIfAbsent(key, value);
    }

    @Override
    public void copyCopyableDataTo(@NotNull UserDataHolderBase clone) {
        this.delegate.copyCopyableDataTo(clone);
    }

    @Override
    public boolean isUserDataEmpty() {
        return this.delegate.isUserDataEmpty();
    }

    @Override
    public int hashCode() {
        return this.delegate.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return this.delegate.equals(obj);
    }
}
